﻿/*
 * Copyright (c) 2009, Thiago M. Sayao <thiago.sayao@gmail.com>
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *  * Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of the author nor the names of its contributors may be 
 *    used to endorse or promote products derived from this software without 
 *    specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Web.Routing;
using System.Xml.Linq;
using System.Web.Mvc;
using System.Text;
using System.Globalization;
using System.IO;
using DotNetBurner.Model;
using DotNetBurner.Core;
using DotNetBurner.Web.Settings;

namespace DotNetBurner
{
    public static class SiteMapHelper
    {
        public static string GenerateSiteMap (Repository repository, UrlHelper urlHelper)
        {
            XNamespace xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";
            var root = new XElement (xmlns + "urlset");

            string siteUrl = SiteSettings.Settings.Address;

            //add main site
            DateTime dt = DateTime.UtcNow;

            string lc = String.Format (CultureInfo.InvariantCulture, "{0:yyyy-MM-dd}", dt);

            //add main site URL
            root.Add (new XElement (xmlns + "url",
                            new XElement (xmlns + "loc", siteUrl),
                            new XElement (xmlns + "priority", "1.0"),
                            new XElement (xmlns + "changefreq", "daily"),
                            new XElement (xmlns + "lastmod", lc)));

            //add categories
            var categories = repository.GetCategories ();

            foreach (Category cat in categories)
            {
                string url = String.Concat(siteUrl,
                                           urlHelper.RouteUrl("Category",
                                                              new RouteValueDictionary
                                                                  {
                                                                      {"id", cat.CategoryId},
                                                                      {"name", cat.Name.ConvertToUrlPath()},
                                                                      {"sort", SwissKnife.GetSortString(0)}
                                                                  }));

                root.Add(new XElement(xmlns + "url",
                                      new XElement(xmlns + "loc", url),
                                      new XElement(xmlns + "changefreq", "weekly")));

                foreach (Category subcat in cat.SubCategories)
                {
                    url = String.Concat(siteUrl,
                                        urlHelper.RouteUrl("Category",
                                                           new RouteValueDictionary
                                                               {
                                                                   {"id", subcat.CategoryId},
                                                                   {"name", subcat.Name.ConvertToUrlPath()},
                                                                   {"sort", SwissKnife.GetSortString(0)}
                                                               }));

                    root.Add(new XElement(xmlns + "url",
                                          new XElement(xmlns + "loc", url),
                                          new XElement(xmlns + "changefreq", "weekly")));
                }
            }

            //add tags
            var tags = repository.GetTags (StorySettings.Settings.TopTags);

            foreach (Tag tag in tags)
            {
                string url = String.Concat(siteUrl,
                                           urlHelper.RouteUrl("Tag",
                                                              new RouteValueDictionary
                                                                  {
                                                                      {"id", tag.TagId},
                                                                      {"name", tag.Name.ConvertToUrlPath()},
                                                                      {"sort", SwissKnife.GetSortString(0)}
                                                                  }));

                root.Add (new XElement (xmlns + "url",
                                new XElement (xmlns + "loc", url),
                                new XElement (xmlns + "changefreq", "weekly")));

            }

            //add upcoming
            string upcoming = String.Concat (siteUrl, urlHelper.RouteUrl("Upcoming"));
            root.Add (new XElement (xmlns + "url",
                            new XElement (xmlns + "loc", upcoming),
                            new XElement (xmlns + "priority", "1.0"),
                            new XElement (xmlns + "changefreq", "daily"),
                            new XElement (xmlns + "lastmod", lc)));

            //add articles
            var links = repository.GetSiteMap();

            foreach (SiteLink link in links)
            {
                string url = String.Concat(
                    siteUrl,
                    urlHelper.RouteUrl("Detail",
                                       new RouteValueDictionary
                                           {{"id", link.StoryId}, {"title", link.Title.ConvertToUrlPath()}}));

                lc = String.Format("{0:yyyy-MM-dd}", link.LastModified);

                root.Add(new XElement(xmlns + "url",
                                      new XElement(xmlns + "loc", url),
                                      new XElement(xmlns + "changefreq", "weekly"),
                                      new XElement(xmlns + "lastmod", lc)));
            }

            var memoryStream = new MemoryStream();
            using (var writer = new StreamWriter(memoryStream, Encoding.UTF8))
                root.Save(writer);

            return Encoding.UTF8.GetString(memoryStream.ToArray());
        }
    }
}
